package extension.room.tienlen;

import extension.room.analyse.CardSet;
import java.util.LinkedList;
import java.util.List;
import log.Debug;

/**
 *
 * @author daz
 */
public class NorthTienlenGame extends TienlenGame implements Runnable {

    NorthTienlenGame(NorthTienlenExtension tienlenExtension, int roomId) {
        super(tienlenExtension, roomId);

    }

    @Override
    public boolean checkCard(List<Integer> listCards) {
        Debug.d("check card :" + listCards.toString());
        int[] cardCheck = new int[listCards.size()];
        int count = 0;
        for (Integer card : listCards) {
            cardCheck[count] = card;
            count++;
        }
        //check hop le
        CardSet set = null;
        boolean isSetValid = true;
        if (count >= 2) {
            set = analyser.extractFlush(cardCheck);
            if (set == null) {
                set = analyser.extractPair(cardCheck);
            }
            if (set == null) {
                isSetValid = false;
            } else if (set.getSetSize() < count) {
                isSetValid = false;
            } else if (set.getType() == CardSet.PAIR && set.getSetSize() == 2) {
                if (!set.checkTwoPair() && set.getCardId(0) % 13 != 1 && set.getCardId(1) % 13 != 1) {
                    isSetValid = false;
                }
            }
        }

        if (set != null) {
            Debug.d("set size :" + set.getSetSize());
        }

        Debug.d(
                "count :" + count);
        Debug.d(
                "is valid :" + isSetValid);


        if (!isSetValid) {
            return false;
        }

        if (lastBlock
                != -1) {
            //check cung loai
            boolean isSameType = false;
            if (count == 1 && currentSet == null && currentCard != -1) {
                if ((currentCard / 13 == cardCheck[0] / 13)
                        || (cardCheck[0] % 13 == 1)) {
                    isSameType = true;
                }
            } else if (currentSet != null && count == currentSet.getSetSize()) {
                if (set.checkSameSet(currentSet) || set.checkSetSpecail()) {
                    isSameType = true;
                }
            } else if (count == 4 && set != null && set.getType() == CardSet.PAIR && currentCard % 13 == 1) {
                isSameType = true;
                isChargePenalty = true;
            }

            Debug.d("same type :" + isSameType);
            if (!isSameType) {
                return false;
            }

            boolean isBigger = false;
            if (set != null) {
                if (currentSet != null) {
                    isBigger = set.isBigger(currentSet);
                    if (isBigger && set.getType() == CardSet.PAIR && set.getSetSize() == 4 && currentSet.getType() == CardSet.PAIR && currentSet.getSetSize() == 4) {
                        isChargePenalty = true;
                    }
                } else if (set.getType() == CardSet.PAIR && set.getSetSize() == 4 && currentCard % 13 == 1) {
                    isBigger = true;
                }
            } else {
                isBigger = (cardCheck[0] - 2 + 13) % 13 > (currentCard - 2 + 13) % 13;
                if (cardCheck[0] % 13 == 1 && currentCard % 13 == 1 && cardCheck[0] / 13 < currentCard / 13) {
                    isBigger = true;
                }

            }
            Debug.d("is bigger :" + isBigger);

            if (!isBigger) {
                return false;
            }
        }
        boolean isRightRule = checkRightRule(listCards);

        if (!isRightRule) {
            return false;
        }

        return true;
    }

    @Override
    public boolean checkRightRule(List<Integer> listCards) {
        boolean isRightRule = true;
        List<Integer> listInHand = listPlayers[gameTurn].getListCardIds();
        Debug.d("number card when check  :" + listInHand.toString());
        int countSpecialInHand = 0;
        for (Integer cardInHand : listInHand) {
            if (cardInHand % 13 == 1) {
                countSpecialInHand++;
            }
        }
        int countSpecialRemove = 0;
        for (Integer remove : listCards) {
            if (remove % 13 == 1) {
                countSpecialRemove++;
            }
        }
        Debug.d("special in hand :" + countSpecialInHand);
        Debug.d("special remove :" + countSpecialRemove);
        if (countSpecialInHand - countSpecialRemove == listInHand.size() - listCards.size() && countSpecialInHand > 0) {
            isRightRule = false;
        }
        Debug.d("is right rule:" + isRightRule);
        return isRightRule;
    }

    @Override
    protected List<Integer> getListBlock() {
        List<Integer> listBlock = new LinkedList<Integer>();
        if (lastBlock != -1) {
            if (currentCard != -1) {
                int cardChoose = listPlayers[gameTurn].getSuggestCard(currentCard);
                if (cardChoose != -1) {
                    listBlock.add(cardChoose);
                } else if (currentCard % 13 == 1) {
                    listBlock.addAll(listPlayers[gameTurn].getSuggestFourOfKind());
                }
            } else if (currentSet != null) {
                List<Integer> listSuggest = listPlayers[gameTurn].getSuggestCard(currentSet);
                listBlock.addAll(listSuggest);
            }
        } else {
            int cardChoose = listPlayers[gameTurn].getSugesstMinCard();
            listBlock.add(cardChoose);
        }
        return listBlock;
    }

    @Override
    protected void extractSet(int[] cardCheck) {
        analyser.extractFlush(cardCheck);
        if (currentSet == null) {
            currentSet = analyser.extractPair(cardCheck);
        }

    }

    @Override
    protected long getMoneyChange() {
        return this.betMoney * 4;
    }

    @Override
    protected void checkRemainCard(TienlenPlayer tienlenPlayer) {
        tienlenPlayer.checkRemainSpecialCard();
    }

    @Override
    public List<Integer> getAutoFightCard() {
        List<Integer> listCards = new LinkedList<Integer>();
        int chooseIndex = 0;
        boolean isChoosed = false;
        do {
            if (!listCards.isEmpty()) {
                listCards.clear();
            }
            int cardChoose = -1;
            if (!isChoosed) {
                cardChoose = listPlayers[gameTurn].getSugesstMinCard();
                isChoosed = true;
                listCards.add(cardChoose);
            } else {
                cardChoose = listPlayers[gameTurn].getListCardIds().get(chooseIndex);
                listCards.add(cardChoose);
                chooseIndex++;
            }
        } while (!checkRightRule(listCards));
        return listCards;
    }

    @Override
    public void updateNumberPlaying() {
        numberPlayings = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                numberPlayings++;
            }
        }
    }
}
